#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import json
import sys
import os
from datetime import datetime
import configparser

"""
v1.0:
1、指定输入文件夹、输出文件夹，批量处理文件
2、调用命令行
3、先扫描出文件，再执行操作并输出
v2.0:
1、增加配置文件，扫描目录，ffmpeg参数等参数均通过配置文件读取
2、增加压字幕脚本
"""

__author__ = 'hubert'


# 递归扫描文件进行处理
def recursive(path, file_list, pix):
    try:
        listdir = os.listdir(path)
    except Exception as ex_path:
        print("源目录异常", str(ex_path))

    for dir_name in listdir:
        if dir_name != ".DS_Store":
            # print("路径：", path + "/" + dir_name)
            if os.path.isdir(path + "/" + dir_name):
                print("目录：", path + "/" + dir_name)
                # 是目录就继续扫描
                recursive(path + "/" + dir_name, file_list, pix)
            else:
                if dir_name.endswith(".ts") or dir_name.endswith(".mp4") or dir_name.endswith(
                        ".mpeg") or dir_name.endswith(".avi"):
                    print("文件：", path + "/" + dir_name)
                    # ffprobe -i /test/6F5C899975164C19B602A8A992FA3169.ts -v quiet -of json -show_streams -select_streams v:0
                    file_path = path + "/" + dir_name
                    base_cmd = "ffprobe -i " + "\"" + file_path + "\"" + " -v quiet -of json -show_streams -select_streams v:0"
                    try:
                        json_str = popen_(base_cmd)
                        json_streams = json.loads(json_str)
                        v_width = json_streams["streams"][0]["width"]
                        v_height = json_streams["streams"][0]["height"]

                        # 处理1080P视频 "1920*1080"
                        if pix == str(v_width) + "*" + str(v_height):
                            # print(str(v_width)+"*"+str(v_height))
                            file_list.append(path + "/" + dir_name)
                        else:
                            print("没有匹配到所需要的处理的视频文件，请检查视频或输入的分辨率参数！！！")
                    except Exception as ex:
                        print('str(ex):\t\t', str(ex))


# 调用命令行
def popen_(command):
    val = os.popen(command).read()
    return val


# 遮标
def delogo_video(file_list, delogo_x, delogo_y, delogo_w, delogo_h):
    """
    # ffmpeg -i input -vf "delogo=x=1600:y=50:w=210:h=60" -c:v h264 -level 4.1 -b:v 7500k -c:a copy -y ouput
    :param file_list:
    :param delogo_x:
    :param delogo_y:
    :param delogo_w:
    :param delogo_h:
    :return:
    """
    base_cmd = "ffmpeg -i "
    """
        GPU：
            MAC： h264_videotoolbox
            windows： h264_nvenc
    """

    if len(file_list) > 0:
        for filename in file_list:
            ouput_file_path = output_path + "/" + datetime.now().strftime('%Y%m%d')
            if not os.path.exists(ouput_file_path):
                os.makedirs(ouput_file_path)
            ouput_file = ouput_file_path + "/" + os.path.basename(filename)
            exe_cmd = base_cmd + "\"" + filename + "\"" + " -vf " + "\"" + "delogo=x=" + str(delogo_x) + ":y=" + \
                      str(delogo_y) + ":w=" + str(delogo_w) + ":h=" + str(delogo_h) + "\"" + " -c:v h264_videotoolbox" \
                      + " " + "-b:v " + str(v_bitrate) + " -c:a copy -y " + "\"" + ouput_file + "\""
            print(exe_cmd)
            val = popen_(exe_cmd)
            # 出差执行过程
            print(val)
            # 分割线
            print("************************************************************************************************")


# 加文字水印
def drawtext_video(file_list, text, text_x, text_y, fontsize, fontcolor, borderw, boxcolor, time_begin, time_end):
    """
    # ffmpeg -i input -vf "drawtext=fontfile=STHeiti Light.ttc:text='测试文字':x=1350:y=800:fontsize=56:fontcolor=white:
    borderw=2:boxcolor=white:enable='between(t,00,30)'" -c:v h264 -level 4.1 -b:v 7500k -c:a copy -y ouput
    :param file_list:
    :param text:
    :param text_x:
    :param text_y:
    :param fontsize:
    :param fontcolor:
    :param borderw:
    :param boxcolor:
    :param time_begin:
    :param time_end:
    :return:
    """
    base_cmd = "ffmpeg -i "
    """
        GPU：
            MAC： h264_videotoolbox
            windows： h264_nvenc
        字体文件：
            window环境下，测试字体绝对路径，一直识别不到，采用相对路径的方式，需要在当前字体文件所在目录执行
    """

    if len(file_list) > 0:
        for filename in file_list:
            ouput_file_path = output_path + "/" + datetime.now().strftime('%Y%m%d')
            if not os.path.exists(ouput_file_path):
                os.makedirs(ouput_file_path)
            ouput_file = ouput_file_path + "/" + os.path.basename(filename)
            exe_cmd = base_cmd + "\"" + filename + "\"" + " -vf "+ "\"" +"drawtext=fontfile=simhei.ttf:text=" + str(text) + ":x=" \
                      + str(text_x) + ":y=" + str(text_y) + ":fontsize=" + str(fontsize) + ":fontcolor=" + str(fontcolor) \
                      + ":borderw=" + str(borderw) + ":boxcolor=" + str(boxcolor) + ":enable='between(t," + str(time_begin) + "," \
                      + str(time_end) + ")'" + "\"" +" -c:v h264_nvenc" + " " + "-b:v " + str(v_bitrate) \
                      + " -c:a copy -y " + "\"" + ouput_file + "\""
            print(exe_cmd)
            val = popen_(exe_cmd)
            # 出差执行过程
            print(val)
            # 分割线
            print("************************************************************************************************")

# 遮标+加文字水印
def both_video(file_list, delogo_x, delogo_y, delogo_w, delogo_h, text, text_x, text_y, fontsize, fontcolor, borderw, boxcolor, time_begin, time_end):
    base_cmd = "ffmpeg -i "
    """
        GPU：
            MAC： h264_videotoolbox
            windows： h264_nvenc
        字体文件：
            window环境下，测试字体绝对路径，一直识别不到，采用相对路径的方式，需要在当前字体文件所在目录执行
    """

    if len(file_list) > 0:
        for filename in file_list:
            ouput_file_path = output_path + "/" + datetime.now().strftime('%Y%m%d')
            if not os.path.exists(ouput_file_path):
                os.makedirs(ouput_file_path)
            ouput_file = ouput_file_path + "/" + os.path.basename(filename)
            exe_cmd = base_cmd + "\"" + filename + "\"" + " -vf " + "\"" + "delogo=x=" + str(delogo_x) + ":y=" \
                      + str(delogo_y)  + ":w=" + str(delogo_w) + ":h=" + str(delogo_h) + ",drawtext=fontfile=simhei.ttf:text=" \
                      + str(text) + ":x=" + str(text_x) + ":y=" + str(text_y) + ":fontsize=" + str(fontsize) + ":fontcolor=" + str(fontcolor) \
                      + ":borderw=" + str(borderw) + ":boxcolor=" + str(boxcolor) + ":enable='between(t," + str(time_begin) + "," \
                      + str(time_end) + ")'" + "\"" +" -c:v h264_nvenc" + " " + "-b:v " + str(v_bitrate) \
                      + " -c:a copy -y " + "\"" + ouput_file + "\""
            print(exe_cmd)
            val = popen_(exe_cmd)
            # 出差执行过程
            print(val)
            # 分割线
            print("************************************************************************************************")


# 解析配置文件
def resolove_config(ini_path):
    cf = configparser.ConfigParser()
    cf.read(ini_path, encoding='UTF-8')
    return cf


# 遮标任务
def delogo_task(cf, input_path, output_path, pix):
    try:
        delogo_x = cf.get("delogo", "delogo_x")
        delogo_y = cf.get("delogo", "delogo_y")
        delogo_w = cf.get("delogo", "delogo_w")
        delogo_h = cf.get("delogo", "delogo_h")
    except Exception as ex_delog:
        print("读取delog配置项异常：", ex_delog)

    file_list = []
    # 递归扫描目录
    recursive(input_path, file_list, pix)
    # 根据获取的文件列表按序执行
    delogo_video(file_list, delogo_x, delogo_y, delogo_w, delogo_h)

def drawtext_task(cf, input_path, output_path, pix):
    try:
        text = cf.get("drawtext", "text")
        text_x = cf.get("drawtext", "text_x")
        text_y = cf.get("drawtext", "text_y")
        fontsize = cf.get("drawtext", "fontsize")
        fontcolor = cf.get("drawtext", "fontcolor")
        borderw = cf.get("drawtext", "borderw")
        boxcolor = cf.get("drawtext", "boxcolor")
        time_begin = cf.get("drawtext", "time_begin")
        time_end = cf.get("drawtext", "time_end")
    except Exception as ex_draw:
        print("读取draw配置项异常：", ex_draw)

    file_list = []
    # 递归扫描目录
    recursive(input_path, file_list, pix)
    # 根据获取的文件列表按序执行
    drawtext_video(file_list, text, text_x, text_y, fontsize, fontcolor, borderw, boxcolor, time_begin, time_end)


def both_task(cf, input_path, output_path, pix):
    try:
        delogo_x = cf.get("delogo", "delogo_x")
        delogo_y = cf.get("delogo", "delogo_y")
        delogo_w = cf.get("delogo", "delogo_w")
        delogo_h = cf.get("delogo", "delogo_h")

        text = cf.get("drawtext", "text")
        text_x = cf.get("drawtext", "text_x")
        text_y = cf.get("drawtext", "text_y")
        fontsize = cf.get("drawtext", "fontsize")
        fontcolor = cf.get("drawtext", "fontcolor")
        borderw = cf.get("drawtext", "borderw")
        boxcolor = cf.get("drawtext", "boxcolor")
        time_begin = cf.get("drawtext", "time_begin")
        time_end = cf.get("drawtext", "time_end")
    except Exception as ex_config:
        print("读取config配置项异常：", ex_config)

    file_list = []
    # 递归扫描目录
    recursive(input_path, file_list, pix)
    # 根据获取的文件列表按序执行
    both_video(file_list, delogo_x, delogo_y, delogo_w, delogo_h, text, text_x, text_y, fontsize, fontcolor, borderw, boxcolor, time_begin, time_end)


# 主程序
if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("输出参数异常，请参考如下命令：python py_file_list2.py config.ini")
        sys.exit()
    # print(sys.argv[1])
    # 配置文件路径
    ini_path = sys.argv[1]
    # 读取配置内容
    cf = resolove_config(ini_path)
    try:
        task_type = cf.get("base", "task_type")
        input_path = cf.get("base", "source_path")
        output_path = cf.get("base", "target_path")
        v_bitrate = cf.get("base", "out_vbitrate")
        pix = cf.get("base", "pix_match")
    except Exception as ex_cf:
        print("读取base配置项异常：", str(ex_cf))
    # print(task_type)

    if task_type == str(1).strip():
        """
            进行遮标任务
        """
        delogo_task(cf, input_path, output_path, pix)
    elif task_type == str(2).strip():
        """
            进行压字幕任务
        """
        drawtext_task(cf, input_path, output_path, pix)
    elif task_type == str(3).strip():
        """
            进行遮标+压字幕任务
        """
        both_task(cf, input_path, output_path, pix)
    else:
        print("任务配置类型异常，请检查配置项！！！")
